﻿#include "animationState_Purify.h"

AnimationState_Purify::AnimationState_Purify()
{
    _pipeGraph = new PipeGraph();
    _pipeGraph->setVertexEmitting(0, false);
    _pipeGraph->setVertexEmitting(1, true);
    _pipeGraph->setVertexEmitting(2, true);
    _pipeGraph->setVertexEmitting(3, true);
    _pipeGraph->setVertexEmitting(4, true);
    _pipeGraph->setVertexEmitting(5, true);
    _pipeGraph->setVertexEmitting(6, true);
    _pipeGraph->updateValveState(QVector<bool>({true, true, true, true, false, true, false, true, true, true, true, true, true, true}));

    _syringeColor.push_back(QColor(211, 22, 55));
    _syringeColor.push_back(QColor(232, 235, 85));
    _syringeColor.push_back(QColor(255, 144, 144));
    _syringeColor.push_back(QColor(177, 235, 113));
    _syringeColor.push_back(QColor(200, 129, 244));
    _syringeColor.push_back(QColor(141, 212, 255));
    _syringeColor.push_back(QColor(251, 170, 105));

    _syringeVolumn = QVector<double>({20, 15, 10, 15, 15, 10, 5});

    _valveState.clear();
    for(int i = 0; i < _valveNum; i ++){
        _valveState.push_back(false);
    }
    _pipeGraph->updateValveState(_valveState);

    reset();
}


AnimationState_Purify::~AnimationState_Purify(){
    if(_pipeGraph)  delete _pipeGraph;
}



void AnimationState_Purify::reset(){

    // 只复位注射器，阀门不复位
//    _valveState.clear();
//    for(int i = 0; i < _valveNum; i ++){
//        _valveState.push_back(false);
//    }
//    _pipeGraph->updateValveState(_valveState);

    // 复位注射器
    _syringePercentage.clear();
    _syringeErrorState.clear();
    _syringeSpeed_target.clear();
    _syringeSpeed_realtime.clear();
    for(int i = 0; i < _syringeNum; i ++){
        _syringePercentage.push_back(SyringeCalculator::getSyringePercentFromInitialPosition(i));
        _syringeSpeed_target.push_back(0);
        _syringeSpeed_realtime.push_back(0);
        _syringeErrorState.push_back(0);
    }
    _wheelPosi = 0;
    _hatNum = 99;
    _dissolveTime = 300;

    _heatingState = false;

    _detector = false;
    _column = true;

    updateLiquidPath();

    emit sigReset();

}

int modNum(int num, int min, int max){
    if(min > max){
        return 0;
    }else if(min==max){
        return min;
    }
    while(num > max){
        num -= (max-min);
    }while(num < min){
        num += (max-min);
    }
    return num;
}

void AnimationState_Purify::turnWheel(int num, double speed){      // 给转动数量和速度

    if(num == 0){
        return;
    }
    int posi0 = _wheelPosi;
    int posi1 = modNum(posi0+num, 0, _wheelNum);
    _wheelPosi = posi1;
    emit sigWheelChanged(posi0, posi1, speed, num>0?1:-1);
}

void AnimationState_Purify::turnWheel_posi(int posi, int direct, double speed){        // 给转动到哪个位置、方向、速度
    if(posi < 0 || posi >= _wheelNum){
        return;
    }
    int posi0 = _wheelPosi;
    int posi1 = posi;
    _wheelPosi = posi;
    emit sigWheelChanged(posi0, posi1, speed, direct>0?1:-1);
}
void AnimationState_Purify::turnWheel_posi(int posi, double speed){    // 给转动到位置、速度，方向自己判断
    if(posi < 0 || posi >= _wheelNum){
        return;
    }
    int posi0 = _wheelPosi;
    int posi1 = posi;


    int gap = std::abs((_wheelPosi<posi?_wheelPosi+_wheelNum:_wheelPosi) - posi);
    int direct = 1;
    if(gap >= 5){
        direct = 1;
    }else{
        direct = -1;
    }
//    qDebug() << "当前位置" << _wheelPosi << "  目标位置" << posi << "  差" << gap << "  方向" << direct;
    _wheelPosi = posi;
    emit sigWheelChanged(posi0, posi1, speed, direct);
}

void AnimationState_Purify::pushHat(){
    _hatNum --;
    emit sigHatPushed();
}

void AnimationState_Purify::pressHat(){
    emit sigHatPressed();
}

void AnimationState_Purify::changeValve(int idx, bool state){
    if(_valveState.size() <= idx){
        qDebug() << "ERROR: [Class]AnimationState_Purify [Func]ChangeValve - index out of range";
        return;
    }
    bool state0 = _valveState[idx];
    bool state1 = state;
    _valveState[idx] = state;

    _pipeGraph->updateValveState(_valveState);

    emit sigValveChanged(idx, state0, state1);

}

void AnimationState_Purify::changeSyringe(int idx, double percentage, double speed){       // 目标位置


    if(_syringePercentage.size() <= idx){
        qDebug() << "ERROR: [Class]AnimationState_Purify [Func]ChangeSyringe - index out of range";
        return;
    }
    percentage = std::max(percentage, 0.0);
    percentage = std::min(percentage, 1.0);
    double percent0 = _syringePercentage[idx];
    double percent1 = percentage;

    _syringePercentage[idx] = percentage;
    emit sigSyringeChanged(idx, percent0, percent1, speed);
}

void AnimationState_Purify::changeSyringe_dp(int idx, double dPercentage, double speed){       // 变化量


//    qDebug() << "移动注射器byDP" << idx << dPercentage << speed;
    if(_syringePercentage.size() <= idx){
        qDebug() << "ERROR: [Class]AnimationState_Purify [Func]ChangeSyringe - index out of range";
        return;
    }
    double percent0 = _syringePercentage[idx];
    double percent1 = percent0 + dPercentage;
//    qDebug() << percent0 << percent1;
    percent1 = std::max(percent1, 0.0);
    percent1 = std::min(percent1, 1.0);


    _syringePercentage[idx] = percent1;
    emit sigSyringeChanged(idx, percent0, percent1, speed);
}

/** @brief 修改注射器速度（显示在卡片上面那个） */
void AnimationState_Purify::changeSyringeSpeedTarget(int idx, double speed){
    if(_syringeSpeed_target.size() <= idx){
        return;
    }
    _syringeSpeed_target[idx] = speed;
}

/** @brief 修改注射器速度（显示在卡片下面那个） */
void AnimationState_Purify::changeSyringeSpeedRealTime(int idx, double speed){
    if(_syringeSpeed_realtime.size() <= idx){
        return;
    }
    _syringeSpeed_realtime[idx] = speed;
}

/** @brief 注射器故障（没啥用） */
void AnimationState_Purify::changeSyringeErrorState(int idx, int state){
    if(_syringeErrorState.size() <= idx){
        return;
    }
    _syringeErrorState[idx] = state;
}

/** @brief 修改加热状态 true加热 false不加热 */
void AnimationState_Purify::changeHeating(bool state){
    _heatingState = state;
}

/** @brief 修改前端显示的速度单位 */
void AnimationState_Purify::changeSpeedUnit(int type){
    _speedUnit = type;
}

/** @brief 返回两个顶点是否连接（用于canvas绘图） */
bool AnimationState_Purify::isVertexConnect(int v1, int v2){
    return _pipeGraph->isVertexConnect(v1, v2);
}

/** @brief 递归路径 */
void recursivePath(TreeNode* node, QVector<int> curPath, QVector<QVector<int>> &res){

    if(node->idx != -1){
        curPath.push_back(node->idx);
        if(node->son.size() == 0){

            res.push_back(curPath);
        }else{
            foreach(TreeNode* nodee, node->son){
                recursivePath(nodee, curPath, res);
            }
        }
    }
}

/** @brief 打印当前的路径 */
void AnimationState_Purify::printCurrentPath(){
    QVector<QVector<int>> paths = getCurrentPath();
    foreach(QVector<int> path, paths){
        QString line;
        foreach(int idx, path){
            line.append("->" + QString::number(idx));
        }
        qDebug() << line;
    }
}

void AnimationState_Purify::setColor(QMap<int, QColor> colorList){
    for(auto iter = colorList.begin(); iter != colorList.end(); iter ++){
        if(iter.key() >= _syringeNum) continue;
        if(iter.key() >= _syringeColor.size()){
            for(int i = _syringeColor.size(); i <= iter.key(); i ++){
                _syringeColor.push_back(QColor(200, 200, 200));
            }
        }
        _syringeColor[iter.key()] = iter.value();
    }
}

QVector<QVector<int>> AnimationState_Purify::getCurrentPath(){
    QVector<QVector<int>> res;

    foreach(TreeNode* node, _pipeGraph->getLiquidPath()){
        recursivePath(node, QVector<int>(), res);       // 把属性结构展开成一条一条的样子
    }

    return res;

}

/** @brief 更新液体路径 */
void AnimationState_Purify::updateLiquidPath(){                //

    QVector<QVector<int>> pathList = getCurrentPath();
    QMap<QString, QVector<int>>  namedPath;

    foreach(QVector<int> path, pathList){
        QString name;
        foreach(int idx, path){
            name.append("->" + QString::number(idx));
        }
        namedPath[name] = path;
    }
    emit sigLiquidChanged(namedPath);

}

/** @brief 设置某个点的注射器是否在吸/打液 */
void AnimationState_Purify::setVertexEmitting(int idx, bool state){
    _pipeGraph->setVertexEmitting(idx, state);
    updateLiquidPath();
}

/** @brief 修改色谱图状态 */
void AnimationState_Purify::changeColumn(bool state){
    _column = state;
}
/** @brief 修改检测器状态 */
void AnimationState_Purify::changeDetector(bool state){
    _detector = state;
}
/** @brief 修改蠕动泵状态 */
void AnimationState_Purify::changePPumpState(int state){
    _pPumpState = state;
}


